﻿// -----------------------------------------------------------------------
// <copyright company="Christoph van der Fecht - VDsoft">
// Copyright (C) Christoph van der Fecht - VDsoft - All Rights Reserved
// Unauthorized copying of this file, via any medium is strictly prohibited,
// unless it is communicated and authorized by the copyright owner.
// </copyright>
// -----------------------------------------------------------------------

namespace SeriesManager.Model
{
    using System;
	using System.Collections.ObjectModel;
    using System.ComponentModel;
	using System.Linq.Expressions;


	/// <summary>
    /// Season that contains all episodes.
    /// </summary>
    public class Season : INotifyPropertyChanged
    {
        /// <summary>
        /// The Series.
        /// </summary>
        private Series series = null;

        /// <summary>
        /// The Number.
        /// </summary>
        private int number = 0;

        /// <summary>
        /// The Episodes.
        /// </summary>
        private ObservableCollection<Episode> episodes = new ObservableCollection<Episode>();

        /// <summary>
        /// Initializes a new instance of the <see cref="Season"/> class.
        /// </summary>
        public Season(Series series, int seasonNumber)
        {
            this.Series = series;
            this.Number = seasonNumber;
        }

        /// <summary>
        /// Occurs when a property changd its value.
        /// </summary>
        public event PropertyChangedEventHandler PropertyChanged;

        /// <summary>
        /// Gets or sets the Series property.
        /// </summary>
        public Series Series
        {
            get
            {
                return this.series;
            }

            set
            {
                if (value == this.series)
                {
                    return;
                }

                this.series = value;
                this.RaisePropertyChanged(this.GetName(x => x.Series));
            }
        }

        /// <summary>
        /// Gets or sets the Number property.
        /// </summary>
        public int Number
        {
            get
            {
                return this.number;
            }

            set
            {
                if (value == this.number)
                {
                    return;
                }

                this.number = value;
                this.RaisePropertyChanged(this.GetName(x => x.Number));
            }
        }

		/// <summary>
		/// Gets or sets the Episodes property.
		/// </summary>
		public ObservableCollection<Episode> Episodes
		{
			get
			{
				return this.episodes;
			}

			set
			{
				if (value == this.episodes)
				{
					return;
				}

				this.episodes = value;
			}
		}

        /// <summary>
        /// Get the name of the provided property.
        /// </summary>
        /// <typeparam name="T">Object that contains the changed property.</typeparam>
        /// <param name="selector">Selector for the property.</param>
        /// <returns>Name of the property.</returns>
        private string GetName<T>(Expression<Func<Season, T>> selector)
        {
            var body = (MemberExpression)selector.Body;
            return body.Member.Name;
        }

        /// <summary>
        /// Raises the p<see cref="PropertyChanged"/> event.
        /// </summary>
        /// <param name="propertyName">Name of the property that changed its value.</param>
        private void RaisePropertyChanged(string propertyName)
        {
            if (this.PropertyChanged != null)
            {
                this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        /// <summary>
        /// Adds the provided episode to the collection.
        /// </summary>
        /// <param name="toAdd"><see cref="Episode"/ to add.></param>
        public void AddEpisode(Episode toAdd)
        {
            if (toAdd == null)
            {
                throw new ArgumentNullException("toAdd", "The episode to add must not be null.");
            }

            this.Episodes.Add(toAdd);
        }
    }
}
